from flask import Blueprint, render_template, request, jsonify, make_response
from app.models import db, ApiInfo
import json
from datetime import datetime
import re

# 创建蓝图
api_bp = Blueprint('api', __name__, url_prefix='/api')

# 统一处理JSON响应，确保UTF-8编码
def json_response(data, status_code=200):
    response = make_response(json.dumps(data, ensure_ascii=False))
    response.headers['Content-Type'] = 'application/json; charset=utf-8'
    response.status_code = status_code
    return response

@api_bp.route('/')
def list_apis():
    """API列表页面"""
    return render_template('api/index.html')

@api_bp.route('/data')
def get_apis():
    """获取API列表数据"""
    # 获取查询参数
    search = request.args.get('search', '')
    page = int(request.args.get('page', 1))
    per_page = int(request.args.get('per_page', 10))
    
    # 构建查询
    query = ApiInfo.query
    
    # 搜索过滤
    if search:
        query = query.filter(
            (ApiInfo.name.ilike(f'%{search}%')) |
            (ApiInfo.path.ilike(f'%{search}%')) |
            (ApiInfo.description.ilike(f'%{search}%'))
        )
    
    # 分页
    pagination = query.order_by(ApiInfo.updated_at.desc()).paginate(page=page, per_page=per_page)
    
    # 构建响应数据
    apis = [api.to_dict() for api in pagination.items]
    
    return json_response({
        'apis': apis,
        'pagination': {
            'current_page': pagination.page,
            'per_page': pagination.per_page,
            'total_items': pagination.total,
            'total_pages': pagination.pages
        }
    })

@api_bp.route('/', methods=['POST'])
def create_api():
    """创建API"""
    data = request.json
    if not data:
        return json_response({
            'success': False,
            'message': '无效的请求数据'
        }, 400)
    
    # 创建API
    api = ApiInfo(
        name=data.get('name', ''),
        method=data.get('method', 'GET'),
        path=data.get('path', ''),
        description=data.get('description', ''),
        headers=data.get('headers', {}),
        params=data.get('params', {}),
        body=data.get('body', {}),
        response=data.get('response', {}),
        tags=data.get('tags', [])
    )
    
    db.session.add(api)
    db.session.commit()
    
    return json_response({
        'success': True,
        'message': 'API创建成功',
        'api': api.to_dict()
    })

@api_bp.route('/<int:api_id>', methods=['GET'])
def get_api(api_id):
    """获取API详情"""
    api = ApiInfo.query.get_or_404(api_id)
    return json_response({
        'success': True,
        'api': api.to_dict()
    })

@api_bp.route('/<int:api_id>', methods=['PUT'])
def update_api(api_id):
    """更新API"""
    api = ApiInfo.query.get_or_404(api_id)
    data = request.json
    if not data:
        return json_response({
            'success': False,
            'message': '无效的请求数据'
        }, 400)
    
    # 更新API
    api.name = data.get('name', api.name)
    api.method = data.get('method', api.method)
    api.path = data.get('path', api.path)
    api.description = data.get('description', api.description)
    api.headers = data.get('headers', api.headers)
    api.params = data.get('params', api.params)
    api.body = data.get('body', api.body)
    api.response = data.get('response', api.response)
    api.tags = data.get('tags', api.tags)
    api.updated_at = datetime.now()
    
    db.session.commit()
    
    return json_response({
        'success': True,
        'message': 'API更新成功',
        'api': api.to_dict()
    })

@api_bp.route('/<int:api_id>', methods=['DELETE'])
def delete_api(api_id):
    """删除API"""
    api = ApiInfo.query.get_or_404(api_id)
    
    db.session.delete(api)
    db.session.commit()
    
    return json_response({
        'success': True,
        'message': 'API删除成功'
    })

@api_bp.route('/import', methods=['POST'])
def import_api():
    """导入API"""
    try:
        # 强制获取JSON数据
        data = request.get_json(force=True)
        if not data:
            return json_response({
            'success': False,
            'message': '请求数据必须为JSON格式'
        }, 400)
            
        import_type = data.get('type', '')
        content = data.get('content', '')
        
        if not import_type or not content:
            return json_response({
            'success': False,
            'message': '导入类型和内容不能为空'
        }, 400)

        if import_type == 'swagger':
            # 处理Swagger导入
            try:
                if not content:
                    return json_response({
                    'success': False,
                    'message': 'Swagger内容不能为空'
                }, 400)
                
                swagger_data = json.loads(content)
                apis = []
                
                # 解析Swagger文档
                paths = swagger_data.get('paths', {})
                for path, methods in paths.items():
                    for method, details in methods.items():
                        if method.lower() in ['get', 'post', 'put', 'delete', 'patch']:
                            api = ApiInfo(
                                name=details.get('summary', path),
                                method=method.upper(),
                                path=path,
                                description=details.get('description', ''),
                                headers={},
                                params={},
                                body={},
                                response={},
                                tags=details.get('tags', [])
                            )
                        
                        # 处理参数
                        for param in details.get('parameters', []):
                            if param.get('in') == 'header':
                                api.headers = api.headers or {}
                                api.headers[param.get('name')] = {
                                    'description': param.get('description', ''),
                                    'required': param.get('required', False),
                                    'example': param.get('example', '')
                                }
                            elif param.get('in') == 'query':
                                api.params = api.params or {}
                                api.params[param.get('name')] = {
                                    'description': param.get('description', ''),
                                    'required': param.get('required', False),
                                    'example': param.get('example', '')
                                }
                        
                        # 处理请求体
                        if 'requestBody' in details:
                            content_type = list(details['requestBody'].get('content', {}).keys())[0] if details['requestBody'].get('content') else 'application/json'
                            schema = details['requestBody'].get('content', {}).get(content_type, {}).get('schema', {})
                            api.body = {
                                'content_type': content_type,
                                'schema': schema
                            }
                        
                        # 处理响应
                        responses = details.get('responses', {})
                        api.response = {
                            'status_codes': list(responses.keys()),
                            'examples': {}
                        }
                        for status, response in responses.items():
                            content_type = list(response.get('content', {}).keys())[0] if response.get('content') else 'application/json'
                            schema = response.get('content', {}).get(content_type, {}).get('schema', {})
                            api.response['examples'][status] = {
                                'content_type': content_type,
                                'schema': schema
                            }
                        
                        db.session.add(api)
                        apis.append(api)
            
                db.session.commit()
                
                return json_response({
                    'success': True,
                    'message': f'成功导入 {len(apis)} 个API',
                    'apis': [api.to_dict() for api in apis]
                })
            except Exception as e:
                db.session.rollback()
                return json_response({
                    'success': False,
                    'message': f'Swagger导入失败: {str(e)}'
                }, 400)
        
        elif import_type == 'curl':
            # 处理curl导入
            try:
                if not content:
                    return json_response({
                    'success': False,
                    'message': 'curl命令不能为空'
                }, 400)
                
                # 改进的curl命令解析
                import re
                import urllib.parse
                
                # 清理Windows转义字符
                content = content.replace('^', '')
                
                # 提取方法（优先处理，避免与URL参数冲突）
                method = 'GET'
                method_match = re.search(r'-X\s+([A-Z]+)', content) or re.search(r'--request\s+([A-Z]+)', content)
                if method_match:
                    method = method_match.group(1)
                
                # 提取URL（改进正则，避免匹配到参数）
                # 寻找http://或https://开头的URL
                url_match = re.search(r'(https?://[^\s\'"]+)', content)
                if not url_match:
                    # 如果没有完整URL，尝试提取路径
                    path_match = re.search(r'curl\s+(?:-[^\s]+\s+)*[\'"]?([^\'"\s]+)[\'"]?', content)
                    if path_match and not path_match.group(1).startswith('-'):
                        url = path_match.group(1)
                    else:
                        return json_response({
                            'success': False,
                            'message': '无法解析curl命令中的URL或路径'
                        }, 400)
                else:
                    url = url_match.group(1)
                
                # 从URL中提取路径
                parsed_url = urllib.parse.urlparse(url)
                path = parsed_url.path
                if not path:
                    path = '/'
                elif not path.startswith('/'):
                    path = '/' + path
                
                # 清理路径末尾的反斜杠和其他特殊字符
                path = path.rstrip('\\').rstrip('`')
                
                # 提取查询参数
                params = {}
                if parsed_url.query:
                    query_params = urllib.parse.parse_qs(parsed_url.query)
                    for key, values in query_params.items():
                        params[key] = values[0] if len(values) == 1 else values
                
                # 提取请求头 - 改进正则表达式处理复杂的转义引号
                headers = {}
                # 更灵活的头处理，支持各种格式
                header_lines = re.findall(r'-H\s+([^-]+?)(?=\s*-|\s*$)', content, re.DOTALL)
                for header_line in header_lines:
                    # 清理引号和多余字符
                    header_line = header_line.strip().strip('"\'').replace('^', '')
                    # 清理开头的反斜杠和引号
                    header_line = header_line.lstrip('\\').lstrip('"\'')
                    if ':' in header_line:
                        parts = header_line.split(':', 1)
                        if len(parts) == 2:
                            header_name = parts[0].strip().strip('"\'')
                            header_value = parts[1].strip()
                            # 清理值末尾的反斜杠和引号
                            header_value = header_value.rstrip('\\').rstrip('"\'')
                            if header_name and header_value:
                                headers[header_name] = header_value
                
                # 提取请求体 - 处理复杂的嵌套JSON
                body = None
                # 首先尝试找到--data-raw或-d参数后的完整JSON
                # 使用更智能的模式匹配复杂的嵌套JSON，考虑转义引号
                
                # 调试日志
                print(f"开始解析请求体，内容长度: {len(content)}")
                
                # 尝试匹配--data-raw或-d参数后的内容
                body_patterns = [
                    r'--data-raw\s+([\'"]?)([\s\S]*?)\1(?=\s*-|\s*$)',  # 匹配到下一个参数或结尾
                    r'-d\s+([\'"]?)([\s\S]*?)\1(?=\s*-|\s*$)',        # 匹配到下一个参数或结尾
                    r'--data\s+([\'"]?)([\s\S]*?)\1(?=\s*-|\s*$)',      # 匹配到下一个参数或结尾
                ]
                
                body_content = None
                for pattern in body_patterns:
                    body_match = re.search(pattern, content, re.DOTALL)
                    if body_match:
                        body_content = body_match.group(2).strip()
                        print(f"找到请求体匹配，长度: {len(body_content)}")
                        print(f"前100字符: {body_content[:100]}")
                        break
                
                if body_content:
                    try:
                        # 多层清理转义字符
                        cleaned_content = body_content
                        
                        # 第一步：移除Windows转义符
                        cleaned_content = cleaned_content.replace('^', '')
                        
                        # 第二步：处理转义引号 - 这是关键步骤
                        cleaned_content = cleaned_content.replace('\\"', '"')
                        cleaned_content = cleaned_content.replace("\\'", "'")
                        
                        # 第三步：处理其他转义序列
                        cleaned_content = cleaned_content.replace('\\\\', '\\')
                        cleaned_content = cleaned_content.replace('\\n', '\n')
                        cleaned_content = cleaned_content.replace('\\t', '\t')
                        
                        # 第四步：清理开头和结尾的引号（如果有）
                        cleaned_content = cleaned_content.strip('"\'')
                        
                        print(f"清理后的内容前200字符: {cleaned_content[:200]}")
                        
                        # 尝试解析JSON
                        body = json.loads(cleaned_content)
                        print("成功解析为JSON")
                        
                    except json.JSONDecodeError as e:
                        print(f"JSON解析失败: {e}")
                        # 如果标准解析失败，尝试更宽松的解析
                        try:
                            # 更激进的清理
                            cleaned = re.sub(r'[\^\\`]', '', body_content)
                            cleaned = cleaned.replace('\\"', '"')
                            body = json.loads(cleaned)
                            print("使用激进清理成功解析为JSON")
                        except Exception as e2:
                            print(f"激进清理也失败: {e2}")
                            # 如果还是失败，尝试手动修复
                            try:
                                # 手动修复常见的JSON问题
                                fixed = body_content.replace('^', '')
                                fixed = fixed.replace('\\"', '"')
                                fixed = re.sub(r'([{,])\s*\"([^"]*)\"\s*:', r'\1"\2":', fixed)
                                body = json.loads(fixed)
                                print("使用手动修复成功解析为JSON")
                            except Exception as e3:
                                print(f"手动修复也失败: {e3}")
                                # 如果所有方法都失败，保持原始字符串
                                body = body_content
                                print("保持原始字符串")
                else:
                    print("未找到请求体内容")
                
                # 创建API
                api = ApiInfo(
                    name=f'从curl导入的{method} {path}',
                    method=method,
                    path=path,
                    description='从curl命令导入',
                    headers=headers,
                    params=params,
                    body=body,
                    response={},
                    tags=['curl导入']
                )
                
                db.session.add(api)
                db.session.commit()
                
                return json_response({
                    'success': True,
                    'message': 'curl命令导入成功',
                    'api': api.to_dict()
                })
            except Exception as e:
                db.session.rollback()
                return json_response({
                        'success': False,
                        'message': f'curl导入失败: {str(e)}'
                    }, 400)
        
        else:
            return json_response({
                'success': False,
                'message': '不支持的导入类型'
            }, 400)
            
    except Exception as e:
        return json_response({
            'success': False,
            'message': f'导入API失败: {str(e)}',
            'error': str(e)
        }, 500)
